// Edge Processing ing...

.text
.align 4
.global sgemm_ukernel_8_8_128b

// #Row_Major
// #sgemm_ukernel_8_8_128b(int _m, int _n, int _k, float alpha, float* _a, float* _b, float* _c, int lda, float beta, int ldb);
// #a0: _m
// #a1: _n
// #a2: _k
// #fa0: alpha
// #a3: _a_ptr
// #a4: _b_ptr
// #a5: _c_ptr
// #a6: lda
// #fa1: beta
// #a7: ldb

#define M     a0
#define N     a1
#define K     a2
#define ALPHA  fa0
#define A_PTR a3
#define B_PTR a4
#define C_PTR a5

#define CTRL_M s0   //控制循环参数
#define CTRL_N s1
#define CTRL_K s2
#define MR     s3
#define NR     s4
#define A0_PTR t0
#define A1_PTR t1
#define A2_PTR t2
#define A3_PTR t3
#define A4_PTR t4
#define A5_PTR t5
#define A6_PTR t6
#define A7_PTR s5
#define B0_PTR s6
#define LDA_Byte a6
#define LDBC_Byte a7
#define A_COL_STRIDE s7
#define C0_PTR s8
#define TEMP1 s9
#define TEMP2 s10
#define TEMP3 s11

#define B0 v0
#define A0 ft0
#define A1 ft1
#define A2 ft2
#define A3 ft3
#define A4 ft4
#define A5 ft5
#define A6 ft6
#define A7 ft7
#define C0 v2
#define C1 v4
#define C2 v6
#define C3 v8
#define C4 v10
#define C5 v12
#define C6 v14
#define C7 v16

#if defined (RVV0p7) || defined (RVV0_7) || defined (rvv0p7) || defined (rvv0_7)
    #define VLE vle.v 
    #define VSE vse.v
    #define VSETVLI_M2 vsetvli t0, zero, e32, m2
    #define VSETVLI_M1 vsetvli t0, zero, e32, m1
#else 
    #define VLE vle32.v 
    #define VSE vse32.v 
    #define VSETVLI_M2 vsetvli t0, zero, e32, m2, ta, ma
    #define VSETVLI_M1 vsetvli t0, zero, e32, m1, ta, ma
#endif

#define VFMACC_VF  vfmacc.vf
#define VFMACC_VV  vfmacc.vv
#define VFMUL_VF   vfmul.vf
#define GATHER     vrgather.vi
#define VXOR       vxor.vv
#define VFADD_VV  vfadd.vv
#define BNE        bne
#define BEQ        beq
#define BEQZ       beqz
#define BNEZ       bnez
#define BGE        bgE
#define BGTZ       bgtz
#define ADDI       addi
#define ADD        add
#define SUB        sub
#define SD         sd
#define LD         ld
#define LI         li
#define DIV        div
#define MUL        mul
#define FCVT       fcvt.s.w
#define FLW        flw
#define FEQ        feq.s
#define VFMV       vfmv.v.f
#define MV         mv

sgemm_ukernel_8_8_128b:

    ADDI sp, sp, -64
    SD s7, 56(sp)
    SD s6, 48(sp)
    SD s5, 40(sp)
    SD s4, 32(sp)
    SD s3, 24(sp)
    SD s2, 16(sp)
    SD s1,  8(sp)
    SD s0,  0(sp)

    VSETVLI_M2

    LI TEMP1, 4
    MV CTRL_N, N
    LI MR, 8
    LI NR, 8
    MUL LDA_Byte, LDA_Byte, TEMP1
    MUL LDBC_Byte, LDBC_Byte, TEMP1 
    MUL A_COL_STRIDE, LDA_Byte, MR       //一个MR距离的字节
    //MUL C_BLOCK_STRIDE, LDBC_Byte, MR    //两个子块距离

    N_LOOP:
        SUB CTRL_N, CTRL_N, NR              //最后大于0则进入边角处理？
        MV CTRL_M, M
        MV A0_PTR, A_PTR
        MV C0_PTR, C_PTR

        M_LOOP:
            SUB CTRL_M, CTRL_M, MR
            MV CTRL_K, K
            MV B0_PTR, B_PTR

            VXOR B0, B0, B0
            VXOR C0, C0, C0
            VXOR C1, C1, C1
            VXOR C2, C2, C2
            VXOR C3, C3, C3
            VXOR C4, C4, C4
            VXOR C5, C5, C5
            VXOR C6, C6, C6
            VXOR C7, C7, C7
            VXOR v18, v18, v18
            VXOR v20, v20, v20
            VXOR v22, v22, v22
            VXOR v24, v24, v24
            VXOR v26, v26, v26
            VXOR v28, v28, v28
            VXOR v30, v30, v30

            ADD A1_PTR, A0_PTR, LDA_Byte
            ADD A2_PTR, A1_PTR, LDA_Byte
            ADD A3_PTR, A2_PTR, LDA_Byte
            ADD A4_PTR, A3_PTR, LDA_Byte
            ADD A5_PTR, A4_PTR, LDA_Byte
            ADD A6_PTR, A5_PTR, LDA_Byte
            ADD A7_PTR, A6_PTR, LDA_Byte

            K_LOOP:
                ADDI CTRL_K, CTRL_K, -1
                
                VLE B0, (B0_PTR)
                FLW A0, (A0_PTR)
                FLW A1, (A1_PTR)
                FLW A2, (A2_PTR)
                FLW A3, (A3_PTR)
                FLW A4, (A4_PTR)
                FLW A5, (A5_PTR)
                FLW A6, (A6_PTR)
                FLW A7, (A7_PTR)
                ADDI A0_PTR, A0_PTR, 4
                ADDI A1_PTR, A1_PTR, 4
                ADDI A2_PTR, A2_PTR, 4
                ADDI A3_PTR, A3_PTR, 4
                ADDI A4_PTR, A4_PTR, 4
                ADDI A5_PTR, A5_PTR, 4
                ADDI A6_PTR, A6_PTR, 4
                ADDI A7_PTR, A7_PTR, 4

                VFMACC_VF C0, A0, B0
                VFMACC_VF C1, A1, B0
                VFMACC_VF C2, A2, B0
                VFMACC_VF C3, A3, B0
                VFMACC_VF C4, A4, B0
                VFMACC_VF C5, A5, B0
                VFMACC_VF C6, A6, B0
                VFMACC_VF C7, A7, B0

                ADD B0_PTR, B0_PTR, LDBC_Byte
                BNEZ CTRL_K, K_LOOP

            VFMUL_VF C0, C0, ALPHA
            VFMUL_VF C1, C1, ALPHA
            VFMUL_VF C2, C2, ALPHA
            VFMUL_VF C3, C3, ALPHA
            VFMUL_VF C4, C4, ALPHA
            VFMUL_VF C5, C5, ALPHA
            VFMUL_VF C6, C6, ALPHA
            VFMUL_VF C7, C7, ALPHA

            ADD TEMP1, C0_PTR, LDBC_Byte
            ADD TEMP2, TEMP1, LDBC_Byte
            ADD TEMP3, TEMP2, LDBC_Byte
            VLE v18, (C0_PTR)
            VLE v20, (TEMP1)
            VLE v22, (TEMP2)
            VLE v24, (TEMP3)
            VFADD_VV C0, C0, v18
            VFADD_VV C1, C1, v20
            VFADD_VV C2, C2, v22
            VFADD_VV C3, C3, v24
            VSE C0, (C0_PTR)
            VSE C1, (TEMP1)
            VSE C2, (TEMP2)
            VSE C3, (TEMP3)

            ADD TEMP1, TEMP3, LDBC_Byte
            ADD TEMP2, TEMP1, LDBC_Byte
            ADD TEMP3, TEMP2, LDBC_Byte
            VLE v26, (TEMP1)
            VLE v28, (TEMP2)
            VLE v30, (TEMP3)
            VFADD_VV C4, C4, v26
            VFADD_VV C5, C5, v28
            VFADD_VV C6, C6, v30
            VSE C4, (TEMP1)
            VSE C5, (TEMP2)
            VSE C6, (TEMP3)

            ADD TEMP1, TEMP3, LDBC_Byte
            VLE v18, (TEMP1)
            VFADD_VV C7, C7, v18
            VSE C7, (TEMP1)

            MUL TEMP2, LDBC_Byte, MR
            ADD C0_PTR, C0_PTR, TEMP2
            ADD A0_PTR, A0_PTR, A_COL_STRIDE
            BGE CTRL_M, MR, M_LOOP
            j M_Edge

        M_Edge:

        LI TEMP1, 4
        MUL TEMP2, TEMP1, NR
        ADD B_PTR, B_PTR, TEMP2
        ADD C_PTR, C_PTR, TEMP2
        BGE CTRL_N, NR, N_LOOP
        j N_Edge

    N_Edge:

    LD s7, 56(sp)
    LD s6, 48(sp)
    LD s5, 40(sp)
    LD s4, 32(sp)
    LD s3, 24(sp)
    LD s2, 16(sp)
    LD s1,  8(sp)
    LD s0,  0(sp)
    ADDI sp, sp, 64
ret

